package com.abe.libfitness.main;

import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Message;
import android.view.ViewTreeObserver;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.abe.libcore.base.screen.OnHandlerListener;
import com.abe.libcore.utils.CommonUtils;
import com.abe.libfitness.R;
import com.abe.libfitness.R2;
import com.abe.libfitness.base.BaseComActivity;
import com.abe.libfitness.entity.ComReceiveDataBean;
import com.abe.libfitness.entity.DataEntity;
import com.abe.libfitness.entity.ExerciseEntity;
import com.abe.libfitness.main.dialog.MotorDialog;
import com.abe.libfitness.utils.ConstantFitness;
import com.abe.libfitness.utils.HtmlHelper;
import com.abe.libfitness.utils.ProtocolV3Utils;
import com.abe.libfitness.widget.FNArcSeekBar;
import com.abe.libfitness.widget.ChartJsHandler;
import com.abe.libfitness.widget.X5WebView;
import com.abe.libquick.api.JsonHelper;
import com.abe.libquick.utils.ScreenHelper;
import com.abe.libquick.utils.quick.EmptyUtils;
import com.google.gson.Gson;
import com.tencent.smtt.export.external.interfaces.JsResult;
import com.tencent.smtt.sdk.WebChromeClient;
import com.tencent.smtt.sdk.WebView;

import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import butterknife.BindView;
import butterknife.OnClick;

public class ExerciseMainV2Activity extends BaseComActivity implements MotorDialog.OnMotorActionListener, OnHandlerListener,
        FNArcSeekBar.OnProgressChangeListener {

    private static final int BALL_HEIGHT_MAX = 400;//最大运动距离
    private static final int MIN_WEIGHT = 5;//最小力量
    private static final int MAX_WEIGHT = 30;//最大力量
    private static final int EXERCISE_CHANGE = 0x001;
    private static final int BALL_CHANGE = 0x002;
    //拉伸状态
    protected int mStatus;
    //记录单次拉伸的最大距离，计算卡路里
    protected int distance4Calorie = 0;
    @BindView(R2.id.item_count)
    TextView itemCount;
    @BindView(R2.id.item_seek_bar)
    FNArcSeekBar itemSeekBar;
    @BindView(R2.id.item_weight)
    TextView itemWeight;
    @BindView(R2.id.item_calorie)
    TextView itemCalorie;
    @BindView(R2.id.item_web_view)
    X5WebView itemWebView;
    @BindView(R2.id.item_ball_line)
    ImageView itemBallLine;
    @BindView(R2.id.item_ball)
    ImageView itemBall;
    @BindView(R2.id.item_clear)
    ImageView itemClear;
    @BindView(R2.id.item_start_stop)
    ImageView itemStartStop;
    boolean isMotorStart;
    private MotorDialog motorDialog;
    private float webViewHeightRatio;
    //柱状数据
    private List<ExerciseEntity> exerciseEntities;
    //次数
    private int mRealCounts;
    //重量
    private int mShowWeight;
    private int weightSetNum;
    //卡路里
    private double calorie;
    private DataEntity dataEntity;
    private int chartHeight = 0;
    private int tempHeight;

    @Override
    protected int getLayoutRes() {
        return R.layout.activity_exercise_main_v2;
    }

    @Override
    protected void initContent() {
        isMotorStart = true;
        weightSetNum = 0;
        mRealCounts = 0;
        mShowWeight = MIN_WEIGHT;
        calorie = 0;
        tempHeight = 0;
        exerciseEntities = new ArrayList<>();
        itemCount.setText(String.valueOf(mRealCounts));
        itemWeight.setText(String.valueOf(mShowWeight));
        itemCalorie.setText(String.valueOf(calorie));
        itemSeekBar.setOnProgressChangeListener(this);
        itemSeekBar.setMaxValue(MAX_WEIGHT);
        itemSeekBar.setMinValue(MIN_WEIGHT);
        getHandler().postDelayed(() -> itemSeekBar.setProgress(MIN_WEIGHT), 500);
        initChart();
        //监听整个布局
        ViewTreeObserver vto = itemWebView.getViewTreeObserver();
        vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                itemWebView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                chartHeight = itemWebView.getMeasuredHeight();
                webViewHeightRatio = chartHeight / (float) ScreenHelper.getScreenHeight();
                refreshChart();
            }
        });
    }

    private void initChart() {
        itemWebView.setBackgroundColor(0); // 设置背景色
        itemWebView.getBackground().setAlpha(0); // 设置填充透明度 范围：0-255
        itemWebView.loadUrl(HtmlHelper.FITNESS);
        itemWebView.setWebViewClient(new X5WebView.CusWebViewClient() {
            @Override// 加载完成
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
            }

            @Override// 加载开始
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                super.onPageStarted(view, url, favicon);
            }
        });
        itemWebView.setWebChromeClient(new WebChromeClient() {
            @Override
            public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                return super.onJsAlert(view, url, message, result);
            }
        });
        itemWebView.addJavascriptInterface(new ChartJsHandler(this), "JsHandler");
    }

    @OnClick(R2.id.item_start_stop)
    public void startStop() {
        if (motorDialog != null && motorDialog.isShowing()) return;
        motorDialog = new MotorDialog(this, !isMotorStart, this);
        motorDialog.show();
    }


    @OnClick(R2.id.item_reduce)
    public void reduce() {
        int progress = itemSeekBar.getProgress();
        if (progress - 1 <= MIN_WEIGHT) progress = MIN_WEIGHT;
        else progress = progress - 1;
        itemSeekBar.setProgress(progress);
    }

    @OnClick(R2.id.item_add)
    public void plus() {
        int progress = itemSeekBar.getProgress();
        if (progress + 1 >= MAX_WEIGHT) progress = MAX_WEIGHT;
        else progress = progress + 1;
        itemSeekBar.setProgress(progress);
    }

    @OnClick(R2.id.item_clear)
    public void clear() {
        mRealCounts = 0;
        calorie = 0;
        itemCount.setText(String.valueOf(mRealCounts));
        itemCalorie.setText(String.valueOf(calorie));
        exerciseEntities.clear();
        refreshChart();
    }

    @Override
    public void dispatchHandleMessage(@Nullable Message message) {
        if (message == null) return;
        switch (message.what) {
            case EXERCISE_CHANGE:
                add(message);
                break;
            case BALL_CHANGE:
                RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) itemBallLine.getLayoutParams();
                params.height = (int) message.obj;
                itemBallLine.setLayoutParams(params);
                break;
        }
    }

    private synchronized void add(Message message) {
        if (message == null) return;
        if (message.what == EXERCISE_CHANGE) {
            ExerciseEntity x = (ExerciseEntity) message.obj;
            if (EmptyUtils.isNotEmpty(x)) {
                exerciseEntities.add(x);
                itemCount.setText(String.valueOf(mRealCounts));
                refreshChart();
            }
        }
    }

    private void refreshChart() {
        List<String> x = new ArrayList<>();
        List<Float> y = new ArrayList<>();
        for (int i = 0; i < exerciseEntities.size(); i++) {
            x.add(exerciseEntities.get(i).weight + "kg");
            y.add(exerciseEntities.get(i).distance);
        }
        Gson gson = JsonHelper.gson(JsonHelper.JSON_NORMAL);
        String js = String.format(Locale.CHINA, "javascript:%s('%s','%s','%s')", "showBar",
                gson.toJson(x), new Gson().toJson(y), String.valueOf(webViewHeightRatio));
        itemWebView.evaluateJavascript(js, CommonUtils.INSTANCE::log);
    }


    @Override
    public void onProgressChanged(FNArcSeekBar seekBar, int progress, boolean isUser) {
        itemWeight.setText(String.valueOf(progress));
        if (!isUser) {
            mShowWeight = progress;
        }
    }

    @Override
    public void onStartTrackingTouch(FNArcSeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(FNArcSeekBar seekBar) {
        mShowWeight = seekBar.getProgress();
        itemWeight.setText(String.valueOf(mShowWeight));
    }


    @Override
    public void onAction(boolean motorStart, boolean confirm) {
        if (motorStart == isMotorStart) return;
        if (confirm) {
            Bundle bundle = new Bundle();
            bundle.putBoolean(ConstantFitness.START_MOTOR, !isMotorStart);
            gotoActivityForResult(MotorStartStopActivity.class, bundle, ConstantFitness.REQUEST_MOTOR_ACTION);
        }
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @androidx.annotation.Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode != RESULT_OK) return;
        if (ConstantFitness.REQUEST_MOTOR_ACTION == requestCode) {
            isMotorStart = !isMotorStart;
            formatMotorStartV();
        }
    }

    private void formatMotorStartV() {
        itemStartStop.setBackgroundResource(isMotorStart ? R.drawable.item_circle_red_ball_01 : R.drawable.item_circle_yellow_border_ball_01);
        itemStartStop.setImageResource(isMotorStart ? R.mipmap.icon_start_r : R.mipmap.icon_start_y);
    }

    @Override
    protected void onDataReceived(ComReceiveDataBean ComRecData) {
        dataEntity = ProtocolV3Utils.parse(ComRecData.bRec);
        onDistance();
        if (dataEntity.getPower() != mShowWeight) {
            weightSetNum++;
            CommonUtils.INSTANCE.log("weightSetNum:" + weightSetNum);
            if (weightSetNum >= 5) {
                weightSet(mShowWeight);
                wBase("收到:" + json(ComRecData.bRec));
                weightSetNum = 0;
            }
        } else {
            weightSetNum = 0;
            wBase("收到:" + json(ComRecData.bRec));
        }
    }

    private void onDistance() {
        float move = dataEntity.getDistance() >= BALL_HEIGHT_MAX ? BALL_HEIGHT_MAX : dataEntity.getDistance();
        move = chartHeight > 0 ? (BALL_HEIGHT_MAX - move) * (chartHeight - 50 * getScale()) / BALL_HEIGHT_MAX : 0;
        localSendMsg(BALL_CHANGE, (int) move);
        //if (dataEntity.getDistance() >= BALL_HEIGHT_MAX * 0.6) { // 检测到距离大于60%最大距离时
        if (dataEntity.getDistance() >= 30) { // 检测到距离大于30
            mStatus = 1; // 拉伸状态变为1
            if (tempHeight < dataEntity.getDistance()) {
                tempHeight = dataEntity.getDistance();
            }
            if (distance4Calorie < dataEntity.getDistance()) {
                distance4Calorie = dataEntity.getDistance();
            }
        }
        // 拉伸状为1并且 检测到距离小于60%最大距离时拉伸状态变为
        //if (mStatus == 1 && dataEntity.getDistance() < BALL_HEIGHT_MAX * 0.6) {
        if (mStatus == 1 && dataEntity.getDistance() < 30) {
            mRealCounts++; // 次数 + 1
            localSendMsg(EXERCISE_CHANGE, new ExerciseEntity(dataEntity.getPower(), tempHeight));
            tempHeight = 0;
            mStatus = 0; // 拉伸状态清除
            if (distance4Calorie >= BALL_HEIGHT_MAX * 0.6 && distance4Calorie < BALL_HEIGHT_MAX * 0.8) {
                calorie = calorie + (dataEntity.getPower() / (180 + (Math.random() * 40)));
            } else if (distance4Calorie >= BALL_HEIGHT_MAX * 0.8 && distance4Calorie < BALL_HEIGHT_MAX * 1.2) {
                calorie = calorie + (dataEntity.getPower() / (130 + (Math.random() * 40)));
            } else {
                calorie = calorie + (dataEntity.getPower() / (80 + (Math.random() * 40)));
            }
        }
        runOnUiThread(() -> {
            itemCount.setText(String.valueOf(mRealCounts));
            itemCalorie.setText(String.format(Locale.CHINA, "%.1f", calorie));
        });
    }

    protected void weightSet(int weight) {
        builder.append("\n****************************力量:设置");
        builder.append(weight);
        builder.append("\n");
        builderW(ConstantFitness.LOG_FLAG_SEND);
        send(ProtocolV3Utils.writePower(weight));
    }
}